﻿using System;
using System.Collections.ObjectModel;
using System.Text;
using Oracle.DataAccess.Client;

namespace ISHotelApp.Database
{
    [Serializable]
    public class PokojTable : DbTable
    {
        public static String TABLE_NAME = "Pokoj";

        public String SQL_SELECT = "SELECT * FROM Pokoj ORDER BY id_pokoje ASC";
        public String SQL_SELECT_page = "SELECT * FROM (SELECT rownum rnum, p.* FROM Pokoj p) WHERE rnum > :ab AND rnum <:bc";
        public String SQL_SELECT_id_pokoje = "SELECT * FROM Pokoj WHERE id_pokoje=:id_pokoje";
        public String SQL_SELECT_list = "SELECT id_pokoje, TO_CHAR(id_pokoje) || ' ' || TO_CHAR(kapacita) || 'os.' AS pokojstring FROM Pokoj ORDER BY id_pokoje ASC";
        public String SQL_INSERT = "INSERT INTO Pokoj (id_pokoje, popis_pokoje, kapacita, cena_pokoje) VALUES (:id_pokoje, :popis_pokoje, :kapacity, :cena_pokoje)";
        public String SQL_UPDATE = "UPDATE Pokoj SET popis_pokoje=:popis_pokoje, kapacita=:kapacita, cena_pokoje=:cena_pokoje WHERE id_pokoje=:id_pokoje";
        public String SQL_DELETE = "DELETE FROM Pokoj WHERE id_pokoje=:id_pokoje";


        public PokojTable()
            : base(TABLE_NAME)
        {
        }

        /**
 * Insert the record.
 **/
        public int Insert(Pokoj Pokoj)
        {
            mDatabase.Connect();
            OracleCommand command = mDatabase.CreateCommand(SQL_INSERT);
            PrepareCommand(command, Pokoj);
            int ret = mDatabase.Insert(command);
            mDatabase.Close();
            return ret;
        }

    /**
         * Update the record.
         **/
        public int Update(Pokoj Pokoj)
        {
            mDatabase.Connect();
            OracleCommand command = mDatabase.CreateCommand(SQL_UPDATE);

            if (Pokoj.popis_pokoje != null)
            {
                command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_popis_pokoje, OracleDbType.Varchar2, Pokoj.popis_pokoje.Length));
                command.Parameters[":" + Pokoj.ATTR_popis_pokoje].Value = Pokoj.popis_pokoje;
            }
            else
            {
                command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_popis_pokoje, OracleDbType.Varchar2, 15));
                command.Parameters[":" + Pokoj.ATTR_popis_pokoje].Value = "NOT PROVIDED";
            }

            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_kapacita, OracleDbType.Decimal));
            command.Parameters[":" + Pokoj.ATTR_kapacita].Value = Pokoj.kapacita;

            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_cena_pokoje, OracleDbType.Decimal));
            command.Parameters[":" + Pokoj.ATTR_cena_pokoje].Value = Pokoj.cena_pokoje;

            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_id_pokoje, OracleDbType.Decimal));
            command.Parameters[":" + Pokoj.ATTR_id_pokoje].Value = Pokoj.id_pokoje;

            int ret = mDatabase.Update(command);
            mDatabase.Close();
            return ret;
        }

        /**
     * Update the record - ONLY CHANGED PARAMETERS
     **/

        public int Update2(Pokoj Pokoj)
        {
            mDatabase.Connect();

            Pokoj oldPokoj = Select(Pokoj.id_pokoje);

            StringBuilder commandString = new StringBuilder();
            commandString.Append("UPDATE Pokoj SET ");

            if (oldPokoj.popis_pokoje != Pokoj.popis_pokoje)
            {
                commandString.Append("popis_pokoje=:popis_pokoje");
            }
            if (oldPokoj.kapacita != Pokoj.kapacita)
            {
                if (oldPokoj.popis_pokoje != Pokoj.popis_pokoje) { commandString.Append(", "); }
                commandString.Append("kapacita=:kapacita");
            }
            if (oldPokoj.cena_pokoje != Pokoj.cena_pokoje)
            {
                if ((oldPokoj.popis_pokoje != Pokoj.popis_pokoje)  || (oldPokoj.kapacita != Pokoj.kapacita)) { commandString.Append(", "); }
                
                commandString.Append("cena_pokoje=:cena_pokoje");
            }

            commandString.Append(" WHERE id_pokoje=:id_pokoje");
            OracleCommand command = mDatabase.CreateCommand(commandString.ToString());

            if (oldPokoj.popis_pokoje != Pokoj.popis_pokoje)
            {
                if (Pokoj.popis_pokoje != null)
                {
                    command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_popis_pokoje, OracleDbType.Varchar2, Pokoj.popis_pokoje.Length));
                    command.Parameters[":" + Pokoj.ATTR_popis_pokoje].Value = Pokoj.popis_pokoje;
                }
                else
                {
                    command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_popis_pokoje, OracleDbType.Varchar2, 15));
                    command.Parameters[":" + Pokoj.ATTR_popis_pokoje].Value = "NOT PROVIDED";
                }
            }
            if (oldPokoj.kapacita != Pokoj.kapacita)
            {
                command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_kapacita, OracleDbType.Decimal));
                command.Parameters[":" + Pokoj.ATTR_kapacita].Value = Pokoj.kapacita;
            }
            if (oldPokoj.cena_pokoje != Pokoj.cena_pokoje)
            {
                command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_cena_pokoje, OracleDbType.Decimal));
                command.Parameters[":" + Pokoj.ATTR_cena_pokoje].Value = Pokoj.cena_pokoje;
            }

            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_id_pokoje, OracleDbType.Decimal));
            command.Parameters[":" + Pokoj.ATTR_id_pokoje].Value = Pokoj.id_pokoje;

            int ret = mDatabase.Update(command);
            mDatabase.Close();
            return ret;
        }





        /**
         * Prepare a command.
         **/

        private void PrepareCommand(OracleCommand command, Pokoj Pokoj)
        {
            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_id_pokoje, OracleDbType.Decimal));
            command.Parameters[":" + Pokoj.ATTR_id_pokoje].Value = Pokoj.id_pokoje;

            if (Pokoj.popis_pokoje != null)
            {
                command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_popis_pokoje, OracleDbType.Varchar2, Pokoj.popis_pokoje.Length));
                command.Parameters[":" + Pokoj.ATTR_popis_pokoje].Value = Pokoj.popis_pokoje;
            }
            else
            {
                command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_popis_pokoje, OracleDbType.Varchar2, Pokoj.popis_pokoje.Length));
                command.Parameters[":" + Pokoj.ATTR_popis_pokoje].Value = "NOT PROVIDED";
            }

            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_kapacita, OracleDbType.Decimal));
            command.Parameters[":" + Pokoj.ATTR_kapacita].Value = Pokoj.kapacita;

            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_cena_pokoje, OracleDbType.Decimal));
            command.Parameters[":" + Pokoj.ATTR_cena_pokoje].Value = Pokoj.cena_pokoje;
        }

        public int CountRow()
        {
            int ret = 0;
            mDatabase.Connect();
            OracleCommand command = mDatabase.CreateCommand("SELECT COUNT(*) FROM Pokoj");
            
            OracleDataReader reader = mDatabase.Select(command);
            reader.Read();
            ret = (int)reader.GetDecimal(0);

            mDatabase.Close();

            return ret;

        }

        public Collection<Pokoj> CreateSQLPage(string pageNo, string pageSize)
        {
            int page = Convert.ToInt32(pageNo);
            int size = Convert.ToInt32(pageSize);

            mDatabase.Connect();
            OracleCommand command = mDatabase.CreateCommand(SQL_SELECT_page);

            command.Parameters.Add(new OracleParameter(":ab", OracleDbType.Decimal));
            command.Parameters[":ab"].Value = (page-1) * size  ;
            command.Parameters.Add(new OracleParameter(":bc", OracleDbType.Decimal));
            command.Parameters[":bc"].Value = ((page - 1) *size) + size + 1;

            OracleDataReader reader = mDatabase.Select(command);
            
            Collection<Pokoj> Pokojs = Read2(reader);
            reader.Close();
            mDatabase.Close();
            return Pokojs;
        } 


        /**
         * Select records.
         **/
        public Collection<Pokoj> Select()
        {
            mDatabase.Connect();
            OracleCommand command = mDatabase.CreateCommand(SQL_SELECT);
            OracleDataReader reader = mDatabase.Select(command);

            Collection<Pokoj> Pokojs = Read(reader);
            reader.Close();
            mDatabase.Close();
            return Pokojs;
        }

        /**
 * Select_list records.
 **/
        public Collection<Pokojlist> Select_list()
        {
            mDatabase.Connect();
            OracleCommand command = mDatabase.CreateCommand(SQL_SELECT_list);
            OracleDataReader reader = mDatabase.Select(command);

            Collection<Pokojlist> pokoj_list = new Collection<Pokojlist>();

            while (reader.Read())
            {
                Pokojlist pokoj1 = new Pokojlist();
                pokoj1.id_pokoje = (int)reader.GetDecimal(0); 
                pokoj1.Pokojstring = reader.GetString(1);
                
                pokoj_list.Add(pokoj1);
            }

            reader.Close();
            mDatabase.Close();
            return pokoj_list;
        }

        /**
         * Select the record.
         **/
        public Pokoj Select(int id_pokoje)
        {
            mDatabase.Connect();
            OracleCommand command = mDatabase.CreateCommand(SQL_SELECT_id_pokoje);

            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_id_pokoje, OracleDbType.Varchar2));
            command.Parameters[":" + Pokoj.ATTR_id_pokoje].Value = id_pokoje;
            OracleDataReader reader = mDatabase.Select(command);

            Collection<Pokoj> Pokojs = Read(reader);
            Pokoj Pokoj1 = null;
            if (Pokojs.Count == 1)
            {
                Pokoj1 = Pokojs[0];
            }
            reader.Close();
            mDatabase.Close();
            return Pokoj1;
        }

        private Collection<Pokoj> Read(OracleDataReader reader)
        {
            Collection<Pokoj> Pokojs = new Collection<Pokoj>();

            while (reader.Read())
            {
                Pokoj Pokoj = new Pokoj();
                Pokoj.id_pokoje = (int)reader.GetDecimal(0);
                if (!reader.IsDBNull(1))
                    if (reader.GetString(1) != "NOT PROVIDED")
                        Pokoj.popis_pokoje = reader.GetString(1);
                Pokoj.kapacita = (int)reader.GetDecimal(2);
                Pokoj.cena_pokoje = (int)reader.GetDecimal(3);
                Pokojs.Add(Pokoj);
            }
            return Pokojs;
        }

        private Collection<Pokoj> Read2(OracleDataReader reader)
        {
            Collection<Pokoj> Pokojs = new Collection<Pokoj>();

            while (reader.Read())
            {
                Pokoj Pokoj = new Pokoj();
                Pokoj.id_pokoje = (int)reader.GetDecimal(1);
                if (!reader.IsDBNull(2))
                    if (reader.GetString(2) != "NOT PROVIDED")
                        Pokoj.popis_pokoje = reader.GetString(2);
                Pokoj.kapacita = (int)reader.GetDecimal(3);
                Pokoj.cena_pokoje = (int)reader.GetDecimal(4);
                Pokojs.Add(Pokoj);
            }
            return Pokojs;
        }

        /**
         * Delete the record.
         */
        public int Delete(int id_pokoje)
        {
            mDatabase.Connect();
            OracleCommand command = mDatabase.CreateCommand(SQL_DELETE);

            command.Parameters.Add(new OracleParameter(":" + Pokoj.ATTR_id_pokoje, OracleDbType.Decimal));
            command.Parameters[":" + Pokoj.ATTR_id_pokoje].Value = id_pokoje;
            int ret;
            try
            {
                ret = mDatabase.Delete(command);
            }
            catch (Exception e)
            {
                throw e;
            }
            mDatabase.Close();
            return ret;
        }
    }
}